/****************************************************************************
**
** Copyright (C) 2010 Tieto Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Tieto Corporation (info.ostrava@tieto.com)
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Tieto.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Tieto gives you certain additional
** rights.  These rights are described in the Tieto Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you have questions regarding the use of this file, please contact
** Tieto at info.ostrava@tieto.com.
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtGui/QPainter>

#include "featurerecognitionmodel.h"
#include "etalonmodel.h"
#include "image.h"

#define ETALON_WIDTH 100;
#define ETALON_HEIGHT 20;

// TODO
double maxPerimeter = 0.0;

FeatureRecognitionTask::FeatureRecognitionTask(FeatureRecognitionModel &model, QObject *parent)
    : BackgroundTask(QString(tr("Recognization")), parent),
    _model(model)
{

}

void FeatureRecognitionTask::doRun()
{
    for (int row = 0; row < _model.rowCount(); row++) {
        _model.recognize(row);
    }
}

void FeatureRecognitionTask::doCancel()
{

}

FeatureRecognitionModel::FeatureRecognitionModel(QObject *parent) :
    FeatureModel(parent)
{
    _etalonModel = new EtalonModel(this);
    QObject::connect(this, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(updateEtalon(QModelIndex,QModelIndex)));
    init();
}

FeatureRecognitionTask* FeatureRecognitionModel::recognizeFeatures()
{
    return new FeatureRecognitionTask(*this);
}

EtalonModel& FeatureRecognitionModel::etalonModel()
{
    return *_etalonModel;
}
void FeatureRecognitionModel::setFeatures(const ItemTable &features)
{
    clear();    
    for (int index = 0; index < features.size(); index++) {
        ItemList items = features[index];        
        appendColumn(items);

    }
    insertColumn(EEtalon);
    insertColumn(ERecognizedType);
    // TODO
    for (int row = 0; row < rowCount(); row++) {
        updateEtalon(row);
        // TODO setFeature(row, ERecognizedType, QVariant(QString("Uncatecorized")));
    }
    init();
}

void FeatureRecognitionModel::updateEtalon(int row)
{    
    FeatureTypes types;
    types << ETODO;
    Features features = collectEtalonFeatures(row, types);
    ColorImage image = createEtalonFeaturesImage(features);
    // TODO setFeature(row, EEtalon, qVariantFromValue(features));
    //QVariant v = feature(row, EEtalon); // TODO
    //Features todo = qVariantValue<Features>(v);
    QModelIndex index = modelIndex(row, EEtalon);
    QStandardItem *item = itemFromIndex(index);
    if (item) {
        item->setIcon(QPixmap::fromImage(image));
    }
}

void FeatureRecognitionModel::recognize(int row)
{
    QString name = feature(row, ERecognizedType).toString();
    Features features;
    Feature TODOfeature;
    TODOfeature.value = qVariantValue<double>(feature(row, ETODO));
    TODOfeature.type = EtalonModel::ETODO;
    features << TODOfeature;
    QString etalonName = _etalonModel->recognize(features);
    if (!etalonName.isNull() && !etalonName.isEmpty()) {
        name = etalonName;
    }
    else {
        name = QString();
    }
    setFeature(row, ERecognizedType, name);
}

Qt::ItemFlags FeatureRecognitionModel::flags(const QModelIndex &index) const
{
    Qt::ItemFlags flags = QAbstractItemModel::flags(index);
    if (index.column() == ERecognizedType) { // TODO
        flags |= Qt::ItemIsEditable;
    }
    return flags;
}

void FeatureRecognitionModel::updateEtalon(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
    int row = topLeft.row();    
    QString name = feature(row, ERecognizedType).toString();
    if (!name.isNull() && !name.isEmpty()) {
        Feature TODOFeature;
        TODOFeature.value = qVariantValue<double>(feature(row, ETODO));
        TODOFeature.type = EtalonModel::ETODO;
        _etalonModel->updateEtalon(name, TODOFeature);
    }
}

void FeatureRecognitionModel::init()
{
    QStringList headerLabels; // TODO headers
    headerLabels <<
            tr("Image") <<
            tr("Etalon") <<
            tr("Type") <<
            tr("TODO");
    setHorizontalHeaderLabels(headerLabels);
}

Features FeatureRecognitionModel::collectEtalonFeatures(int row, FeatureTypes &types)
{
    Features features;
    for (int type = 0; type < types.size(); type++) {
        Feature feature;
        feature.value = 0.0;
        feature.type = types[type];
        QVariant variant = this->feature(row, types[type]);        
        if (variant.isValid()) {
            feature.value = variant.toDouble();
        }
        features << feature;
    }    
    return features;
}

double FeatureRecognitionModel::computeMaximum(FeatureType type)
{
    double max = 0.0;
    for (int row = 0; row < rowCount(); row++) {
        QVariant variant = this->feature(row, type);
        if (variant.isValid()) {
            double value = variant.toDouble();
            max += value;
        }
    }
    return max;
}

ColorImage FeatureRecognitionModel::createEtalonFeaturesImage(const Features &features)
{
    int etalonWidth = ETALON_WIDTH;
    int etalonHeight = ETALON_HEIGHT;
    ColorImage image = ColorImage(etalonWidth, etalonHeight);
    QPainter painter(&image);
    QPen pen(Qt::SolidLine);
    pen.setWidth(2);
    QRect etalonRect(0, 0, etalonWidth, etalonHeight);
    painter.fillRect(etalonRect, Qt::green); // TODO
    for (int index = 0; index < features.size(); index++) {
        Feature feature = features[index];
        double max = computeMaximum((FeatureRecognitionModel::FeatureID)(feature.type));
        int featureX = 0;
        if (max) {
            featureX = feature.value / max * etalonWidth;
        }
        painter.drawLine(featureX, 0, featureX, etalonHeight);

    }
    return image;
}


